{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.方法一：解线性方程组计算得到线性回归模型的参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(50, 500)\n",
      "(50, 1)\n"
     ]
    }
   ],
   "source": [
    "A=np.array(pd.read_csv('randn_data_regression_A.csv',header=None))# 读取randn_data_regression_A.csv中的所有值，并保存为np.array格式\n",
    "b=np.array(pd.read_csv('randn_data_regression_b.csv',header=None))# 读取randn_data_regression_b.csv中的所有值，并保存为np.array格式\n",
    "print(A.shape)\n",
    "print(b.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def linear_equation(A,b):# 解线性方程组法求解线性回归模型参数\n",
    "    n = A.shape[1]#获得A的行数\n",
    "    X=np.zeros(n)#创建一个全0列表，用于存储参数值\n",
    "    A=np.hstack((np.ones((50,1)),A))# 在A的左侧生成一列全一的列\n",
    "    X=np.dot(np.dot(np.linalg.inv(np.dot(A.T,A)),A.T),b)#公式求解参数\n",
    "    return X.T\n",
    "        \n",
    "        \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 501)\n",
      "[[ 1.46141005e+03 -1.96779722e+03  2.90614845e+03  6.64806107e+02\n",
      "  -3.62055422e+03  4.77802752e+03 -7.77435186e+03 -1.39453399e+04\n",
      "  -1.74873551e+03  3.92235389e+03  2.74527185e+03  1.35130514e+04\n",
      "  -6.60378999e+03 -1.93342361e+03  2.76844469e+02  4.29051832e+03\n",
      "  -5.80821317e+03 -2.49602405e+03 -7.33380573e+03 -1.57414991e+02\n",
      "  -1.04090015e+03 -6.73495717e+03  4.78948808e+03  9.30542849e+03\n",
      "  -1.06419166e+03 -2.88427041e+03 -8.55535468e+03  1.19603155e+03\n",
      "   2.61051364e+03  3.29942050e+03 -9.27848048e+03 -1.00880229e+03\n",
      "   8.38953655e+02 -1.08985111e+03  8.28299373e+03  6.39562307e+03\n",
      "  -3.89571120e+03 -1.72731359e+03 -4.88978567e+03  5.88117460e+02\n",
      "   1.12252298e+01 -7.29872699e+03  1.57815262e+03  1.57358522e+03\n",
      "   3.69912635e+03 -3.13637973e+03 -5.48900723e+03 -2.29769164e+03\n",
      "  -1.53661057e+03  8.68458340e+03 -5.78321958e+03  6.90954098e+03\n",
      "  -8.50124841e+03 -4.05466430e+03  4.25284886e+03 -2.89865880e+02\n",
      "   4.29196050e+03  3.72242330e+03  1.31176407e+04  2.53698327e+03\n",
      "   2.58371065e+03 -4.43293697e+03  4.69617323e+03  2.64951616e+03\n",
      "  -3.22594887e+03  1.27299004e+03  3.66888777e+03 -7.05979532e+02\n",
      "   1.29018584e+03 -3.93147435e+03 -1.68942060e+03  1.05799491e+03\n",
      "  -5.66093782e+03 -1.86609891e+03 -3.43597386e+03  3.00851452e+03\n",
      "  -2.85517603e+02  4.03698761e+03  9.20962566e+02 -3.28238181e+03\n",
      "   3.72634329e+03  8.19664780e+03 -2.23954502e+03 -7.32503858e+03\n",
      "  -1.92381216e+03  7.00692798e+03  6.39721288e+03 -3.73874157e+03\n",
      "   5.04747234e+03  7.94269205e+02 -1.87997398e+03 -1.19322573e+02\n",
      "  -4.10857643e+03  2.95398448e+03 -4.31932507e+02 -1.80960166e+03\n",
      "   1.65056103e+03  1.98679124e+02 -3.80283036e+03  4.17475566e+03\n",
      "   3.56557279e+02 -5.61474609e+03  6.38301728e+03  4.11620447e+03\n",
      "  -3.00211436e+03  2.73813186e+03  3.81384666e+02  2.76704236e+03\n",
      "   1.01940606e+04 -4.11689247e+03  4.03426118e+02  9.88487129e+02\n",
      "  -4.22871342e+03 -2.12906144e+03  2.03759585e+03  3.33877306e+03\n",
      "   5.19361335e+03 -5.04446520e+02  1.53472063e+03 -1.61524342e+03\n",
      "  -7.93645946e+03 -1.59959197e+03  5.27649999e+03  3.24576360e+03\n",
      "   3.71775434e+03  2.28772426e+03 -2.03284663e+03 -5.22032730e+03\n",
      "   3.16201314e+03  4.29984456e+03 -9.66113031e+02  1.24684723e+03\n",
      "   1.22172673e+03 -6.75650960e+02  5.81299320e+02  3.77829052e+03\n",
      "  -1.15077786e+03  1.45297024e+03  3.56479449e+02  1.34239224e+03\n",
      "  -7.19215681e+03 -2.53752325e+03 -3.80130044e+03 -9.05660221e+01\n",
      "  -4.00592014e+03 -3.08699763e+02  1.85127573e+02  9.17047728e+02\n",
      "  -5.61084408e+03 -3.55201197e+03 -1.79318972e+03  8.36703580e+02\n",
      "  -3.13738486e+02 -3.22029700e+02 -1.46304034e+02  4.41609105e+03\n",
      "   1.61035810e+02  4.03102130e+02 -8.79754041e+02  3.82307630e+03\n",
      "   1.33199399e+02  4.47553424e+03  5.47855293e+02 -1.26464037e+03\n",
      "  -9.84864734e+02  4.56841842e+03  1.10658102e+03  5.27559104e+02\n",
      "  -2.74909078e+02 -7.07273601e+03  8.29501251e+02  3.28242717e+03\n",
      "   4.70305541e+02  1.62277467e+02  8.33130852e+01  4.23075551e+03\n",
      "  -8.61777195e+02  2.32101569e+02 -2.58377886e+03  6.44808361e+02\n",
      "  -2.85748280e+03  1.44759993e+03  1.89240535e+03  3.74760823e+03\n",
      "  -3.20924575e+03 -2.87850189e+03  9.87120799e+02  3.58053018e+02\n",
      "  -1.20047675e+03 -1.62550914e+03 -2.76147511e+03  1.54423654e+03\n",
      "   4.56324439e+03  3.83493183e+03  4.67240519e+03 -2.33174848e+03\n",
      "   8.59317702e+02 -1.99594568e+03 -9.66635336e+01 -7.25676471e+02\n",
      "   1.44658589e+03  9.32123096e+02 -2.07378955e+03 -1.74513920e+03\n",
      "   1.45816164e+03 -2.20655689e+03 -1.08683680e+03  2.74731921e+02\n",
      "   5.10345073e+02 -7.11730086e+02 -4.84059064e+03  1.66080622e+03\n",
      "  -5.28335599e+02  6.45298618e+02 -1.99982309e+03 -1.80543010e+03\n",
      "  -8.70930939e+02 -3.34733191e+03  8.82974237e+02 -2.92703199e+03\n",
      "  -2.16613818e+03 -3.77599136e+02  1.21314823e+03 -2.57986192e+03\n",
      "  -3.07530445e+03  3.96587859e+02 -1.20594298e+03  7.92630414e+02\n",
      "  -3.40670026e+02 -2.68385978e+02 -1.48907014e+03 -6.28394478e+02\n",
      "   6.79857562e+02 -3.52265143e+03  6.85273698e+02  3.85564063e+00\n",
      "  -1.45552295e+03 -2.06832490e+03  1.04878045e+03 -5.09260156e+02\n",
      "   3.13519310e+02  1.15470510e+03 -1.54712317e+03 -1.51778244e+03\n",
      "   4.79470910e+02  8.04596667e+02 -5.61974282e+02 -7.98535407e+02\n",
      "  -4.55999198e+03 -2.00158550e+01 -8.56022405e+02  6.27252393e+02\n",
      "   1.37905427e+03  1.02635319e+03 -1.00653431e+03 -7.13619816e+02\n",
      "   2.58989561e+03  1.41422804e+02 -1.47097955e+03  8.76992228e+02\n",
      "   6.59370641e+02  6.11452027e+02 -3.23424064e+03 -6.18384928e+02\n",
      "   2.27679194e+03  9.16743840e+02 -4.07756849e+03 -9.12584025e+02\n",
      "  -1.69518775e+03  2.46884817e+02  8.74363995e+01  2.46930000e+02\n",
      "   3.99518725e+01  7.79147367e+02  9.81996664e+02  1.72352865e+03\n",
      "   8.13279528e+02 -9.36567306e+02 -2.43910957e+02  3.91559376e+03\n",
      "  -8.40535463e+02 -1.75927431e+03 -1.62857696e+03 -2.54806913e+03\n",
      "   2.82776502e+02  2.63112353e+03  1.27456892e+02  5.84282641e+02\n",
      "  -1.65048061e+03 -1.43017197e+02  7.25474046e+02  9.06470737e+02\n",
      "  -2.06322317e+03  6.04204565e+02  9.42068408e+02  2.34030550e+03\n",
      "  -7.65928458e+02 -3.31577457e+02  2.39082029e+03 -3.02703788e+02\n",
      "  -1.28173307e+03  5.36647567e+02 -8.24611628e+02 -3.22448673e+02\n",
      "  -7.64731650e+02 -3.09193382e+02 -6.37100094e+02  1.84705057e+03\n",
      "   8.62545736e+02 -3.28656925e+02  5.59817371e+02  4.01723555e+02\n",
      "   1.39548120e+03 -1.03721899e+03 -9.19027863e+02 -3.64145851e+02\n",
      "   6.39156696e+02  3.99785667e+02 -1.70868382e+02 -7.55317312e+02\n",
      "  -6.42733409e+02  1.71041328e+03  7.58958100e+02  3.02095181e+02\n",
      "  -7.14583455e+02  8.85555957e+02 -1.52179364e+03  5.05626710e+02\n",
      "  -1.01843324e+03  2.25638363e+03  4.09113282e+01  7.52356301e+02\n",
      "   3.53022828e+02 -5.12598670e+02 -3.94078019e+02 -1.33850996e+02\n",
      "   8.20941181e+02 -1.99791337e+03  1.84683581e+03 -1.91592553e+02\n",
      "   6.08617076e+02  3.14377617e+02 -1.41424780e+03 -9.85512110e+02\n",
      "  -7.65519939e+02 -6.19069210e+02  4.81419830e+02 -1.84315429e+02\n",
      "  -1.34046209e+03 -1.06822698e+02  5.80809487e+02 -2.08163016e+01\n",
      "   7.58123537e+02  1.67116726e+03  1.79732653e+02 -6.02623169e+01\n",
      "  -5.89421761e+02  5.62793776e+02 -7.54269450e+02  3.47051950e+02\n",
      "  -1.43632411e+02  5.60400829e+02 -3.66013128e+02  6.34605805e+02\n",
      "   6.96470974e+01 -7.38094014e+02 -1.11003501e+03  7.86943862e+02\n",
      "  -4.64694921e+01  5.34573024e+02  2.58592105e+02 -2.76308693e+02\n",
      "  -2.32391298e+02  5.83735655e+02 -2.86265801e+02  1.89850354e+00\n",
      "  -7.87059993e+02  1.48532837e+03 -6.99882784e+02 -3.24485389e+02\n",
      "  -1.73723676e+01  1.37691138e+03  1.44766082e+02  2.21813973e+02\n",
      "  -4.69450072e+02 -6.33443680e+02  2.99984646e+02 -7.38539430e+02\n",
      "  -1.34517496e+03  1.06891304e+03  1.74537909e+02  1.59692351e+03\n",
      "   1.67780958e+03 -5.33989936e+00 -3.30580020e+02 -7.09440079e+02\n",
      "  -6.14986833e+02  1.07849697e+03  1.31152032e+02 -9.16267078e+01\n",
      "   1.17156531e+03  9.40652378e+02 -2.35064305e+02 -2.68529352e+02\n",
      "  -1.01571372e+02 -3.40451310e+02  6.01387724e+02  1.13476975e+02\n",
      "  -5.56173565e+02  3.94386275e+02  7.23067816e+02 -1.65649283e+02\n",
      "  -2.01539834e+02 -7.64171980e+02 -1.34750710e+02 -1.44197135e+03\n",
      "   5.13197038e+00 -1.51539446e+02 -1.14826987e+03 -5.26106482e+02\n",
      "   3.67370415e+02 -1.36496105e+02 -7.55249816e+02 -2.18553682e+02\n",
      "  -5.49976348e+02 -4.84645240e+01  1.81114819e+02 -2.02003390e+01\n",
      "   5.35754767e+02  3.59695235e+01  5.24355954e+01  6.07122881e+02\n",
      "   1.01549211e+02 -6.59598271e+02  2.40474230e+01  3.03065035e+02\n",
      "  -4.32684219e+01 -2.38557212e+02  1.97077562e+02 -3.29890590e+02\n",
      "   1.21627230e+02 -5.48359526e+01  1.29740616e+02  2.67578018e+01\n",
      "   2.60157899e+02  2.40630139e+02  1.16917640e+02 -3.41504898e+02\n",
      "  -1.90991438e+02 -7.97022249e+02  7.37534752e+01 -4.22781917e+02\n",
      "   6.55396757e+01  1.62499394e+02  1.66753947e+02  7.52760390e+01\n",
      "  -4.22870085e+00  3.34164064e+02  8.41836240e+00 -1.07928215e+02\n",
      "   2.72976890e+01 -1.52296856e+02  1.68532886e+02  2.56402580e+02\n",
      "   5.20738043e+01 -2.37936604e+02  1.29128214e+02  1.61148613e+01\n",
      "  -2.61343542e+01  1.96475785e+02  2.57044191e+02  1.22684024e+02\n",
      "  -1.78564135e+02 -2.22377376e+01 -8.05301881e+01  2.18361577e+02\n",
      "  -1.03717998e+02 -1.81485533e+02  1.29047757e+02 -2.60385774e+02\n",
      "  -1.19994054e+02  1.17186223e+02 -4.55243213e+00  1.41084300e+02\n",
      "   1.50137815e+02 -1.66668422e+02 -1.76108589e+02  3.43416391e+02\n",
      "  -2.66632455e+01  1.31080548e+02 -2.60185304e+02  6.38177725e+01\n",
      "  -7.04815645e+01  2.43722058e+02  5.04842021e+01 -1.17618439e+02\n",
      "  -1.25678411e+01 -6.47437345e+00 -2.43788429e+01  2.90339197e+01\n",
      "  -1.99601134e+02]]\n"
     ]
    }
   ],
   "source": [
    "X=linear_equation(A,b)#调用方法，用解方程组的方法求解线性回归模型参数值并返回给X\n",
    "print(X.shape)\n",
    "print(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.方法二：利用梯度下降法计算线性回归模型的参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 227,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 228,
   "metadata": {},
   "outputs": [],
   "source": [
    "#计算损失\n",
    "def loss_s(A,b,X):\n",
    "    loss=np.sum((np.dot(A,X)-b)**2)\n",
    "    return loss/(A.shape[1]*2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 229,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gradient(A,b,X):#计算梯度方向\n",
    "    grad=np.empty(len(X))#新建一个和X长度相等的空np数组\n",
    "    grad[0]=np.sum(A.dot(X)-b)\n",
    "    for i in range(1,len(X)):\n",
    "        grad[i]=(((A.dot(X)-b).dot(A[:,i]))[0])\n",
    "    return grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 230,
   "metadata": {},
   "outputs": [],
   "source": [
    "#梯度下降法求参数\n",
    "def train(A,b,X,lr,td):\n",
    "    x = []\n",
    "    y = []\n",
    "    plt.ion()\n",
    "    epoch=0\n",
    "    while 1+1==2:\n",
    "        last_X=X\n",
    "        grad=gradient(A,b,X)\n",
    "        X=X-lr*grad\n",
    "        #绘图\n",
    "        x.append(epoch)\n",
    "        y.append(abs(loss_s(A,b,X)-loss_s(A,b,last_X)))# \n",
    "#         print(f\"epoch {epoch}:精度为：{abs(loss_s(A,b,X)-loss_s(A,b,last_X))}\")\n",
    "        if abs(loss_s(A,b,X)-loss_s(A,b,last_X))<td:\n",
    "            print(f\"迭代总次数为{epoch}\")\n",
    "            break\n",
    "        elif epoch>3000 or loss_s(A,b,X)>loss_s(A,b,last_X):\n",
    "            print(\"该函数无法收敛！\")\n",
    "            break\n",
    "        epoch+=1\n",
    "    plt.plot(x, y)  # 画出当前x列表和y列表中的值的图形\n",
    "    plt.show()\n",
    "    return X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 231,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(50, 500)\n",
      "(50, 1)\n"
     ]
    }
   ],
   "source": [
    "A=np.array(pd.read_csv('randn_data_regression_A.csv',header=None))# 读取randn_data_regression_A.csv中的所有值，并保存为np.array格式\n",
    "b=np.array(pd.read_csv('randn_data_regression_b.csv',header=None))# 读取randn_data_regression_b.csv中的所有值，并保存为np.array格式\n",
    "A=A\n",
    "print(A.shape)\n",
    "print(b.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 232,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "迭代总次数为2064\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 8.08310042e-01  8.66110376e-03  1.30992904e-02 -5.38092254e-02\n",
      " -4.94395159e-03 -7.42392030e-03 -2.83070033e-02 -1.20546620e-02\n",
      "  7.60793366e-03 -3.88534852e-04 -6.66629332e-02  4.43799885e-02\n",
      " -7.56312854e-02  2.48593715e-02  1.25733077e-03 -1.50862680e-02\n",
      " -1.06771327e-02  3.37517888e-02  1.16703056e-02 -4.39752407e-02\n",
      " -2.37200034e-02 -3.21880980e-02  3.46432673e-02 -1.89302121e-02\n",
      " -2.76695792e-02 -1.56517372e-02 -2.14176506e-02  2.15666721e-02\n",
      "  5.22627831e-02  2.64281238e-02  4.04360226e-02  2.29480512e-02\n",
      "  5.11417081e-02  7.14281325e-02  1.85366776e-02 -3.51541738e-02\n",
      " -2.09483071e-03 -9.67323144e-03 -2.73576281e-02  4.77543336e-02\n",
      "  6.27544836e-03  5.29863967e-02  4.53699898e-03  1.09604589e-04\n",
      "  5.98496929e-03 -5.30081438e-03  1.66798672e-02  8.50600606e-02\n",
      " -2.34111437e-02 -7.09796516e-03  3.86473320e-02 -5.02752128e-02\n",
      "  6.27634086e-02  5.84915099e-02 -6.89569138e-02 -2.12075445e-02\n",
      " -1.29887156e-02 -1.96920139e-02 -1.35520077e-02  2.61837555e-02\n",
      " -4.37133228e-02  5.88018709e-03 -4.30397836e-03 -7.60459903e-03\n",
      " -2.88649888e-02  4.62005581e-03  3.11976301e-02  7.80439655e-03\n",
      "  1.57487237e-02  5.46923852e-02  2.66174609e-03 -5.72468139e-02\n",
      " -1.56336332e-02  3.19066567e-02  3.67453729e-02 -7.45454520e-03\n",
      " -3.75291859e-02  1.59012320e-02  5.97913837e-03  2.15767000e-02\n",
      "  4.64913475e-02 -3.87576716e-03 -1.24637053e-02  8.64161813e-03\n",
      " -4.22631461e-02 -2.19615555e-02  2.02219673e-02  1.08652430e-02\n",
      " -1.00566880e-02  2.98999678e-02 -4.64754219e-02  3.29141597e-02\n",
      "  9.97362693e-03 -3.14570624e-02  1.62315368e-02 -6.30889401e-03\n",
      " -9.08900500e-04  3.86048079e-02 -2.27843382e-02  1.40561245e-02\n",
      "  4.81370141e-03 -1.93754464e-02  2.84134359e-02 -2.83638748e-02\n",
      "  5.41809465e-02 -3.44258207e-02 -5.04633142e-02 -2.86625574e-03\n",
      "  7.19610047e-04 -7.04485847e-02  6.91924335e-02 -1.04874934e-02\n",
      " -1.98792413e-02  3.22518040e-02 -2.18630444e-02 -7.14843464e-02\n",
      " -2.15430374e-03  7.31443559e-02  3.31005068e-02  6.91868690e-03\n",
      " -3.63879899e-02 -1.59121548e-02 -3.49042605e-02  4.14130882e-02\n",
      "  5.64637729e-02  1.49030787e-02  6.89511251e-03 -5.37473458e-02\n",
      "  9.78261157e-03 -1.21493523e-02  6.63253095e-02  1.95431945e-02\n",
      "  5.87355762e-03 -7.15589993e-02  1.26020101e-02  7.27622813e-03\n",
      "  1.10349378e-02 -1.83505570e-02 -5.17718833e-02 -2.56798106e-02\n",
      " -4.96407588e-04  1.56746246e-02 -1.57030461e-02 -3.21519074e-02\n",
      " -8.46569113e-03 -5.41026112e-02 -3.72472068e-02  1.59749723e-02\n",
      "  9.87062693e-03 -1.65184228e-02 -5.77123030e-02 -1.78257456e-03\n",
      "  2.98106081e-02  5.38091105e-02  3.27039654e-02 -2.47728994e-02\n",
      "  1.66822029e-02 -1.91991908e-02  3.43596642e-02  1.59087274e-02\n",
      "  4.72347177e-02 -2.80998725e-02 -2.22925474e-02  2.31096841e-02\n",
      "  1.71435568e-02 -1.09036766e-02 -5.75747659e-02 -2.36750348e-02\n",
      "  2.74798225e-02 -1.63190627e-02  1.73834321e-02  2.63527248e-03\n",
      " -3.08075150e-02  7.89978340e-02  8.01355722e-02 -4.54100858e-02\n",
      " -3.09192686e-02 -3.62377777e-02 -1.01680055e-02  2.71585967e-02\n",
      " -4.36062450e-02  5.26233330e-02  2.00267449e-02  5.45326074e-02\n",
      "  6.86972901e-03  2.86489145e-02 -4.09017809e-02  2.40640715e-02\n",
      " -1.23909362e-02 -4.56150859e-03 -2.57908904e-02 -1.19384663e-02\n",
      "  3.78555675e-02 -6.08352795e-02  2.76149606e-02 -8.15557476e-02\n",
      " -1.74404436e-02  2.66138248e-02 -2.88407080e-02  4.95325723e-02\n",
      " -1.20144576e-02 -1.30689348e-03  4.37528292e-02  3.30914549e-03\n",
      " -6.34478989e-03 -1.84669595e-02 -8.08322030e-03  6.73287751e-03\n",
      "  4.48568044e-02  1.69130677e-02  1.47100139e-02  1.69849921e-02\n",
      "  2.41763487e-02 -3.85104302e-03  6.49394786e-03 -6.14735093e-03\n",
      "  5.51707372e-02 -2.38637892e-02  3.30568252e-03  5.11574456e-02\n",
      " -2.85507729e-03 -3.77685688e-02  2.71376097e-03 -8.68765229e-03\n",
      " -8.98338238e-03  3.54318193e-02  4.29360711e-02  2.37148799e-02\n",
      " -1.98516749e-03  1.88927871e-02  3.72674199e-02  2.91888985e-02\n",
      " -1.10838700e-02 -2.86584291e-02  5.49337451e-03 -7.45412279e-03\n",
      "  2.03392531e-02  9.34664720e-03 -3.47125684e-02 -1.06469687e-02\n",
      "  1.84035725e-03  1.82406776e-02 -9.08142806e-03 -4.53343640e-02\n",
      " -2.95101467e-02 -2.24459912e-02  2.16328207e-02 -2.52319171e-02\n",
      "  3.02385139e-04  2.15109487e-02  2.95256233e-02  1.38121920e-02\n",
      " -1.23974252e-02  2.28532622e-02  4.37909197e-02  4.01628623e-02\n",
      " -1.57050913e-02  2.28274095e-02  1.01028160e-02 -2.60156815e-02\n",
      " -2.36846474e-02 -1.48201776e-02 -3.65284816e-03  6.79655837e-03\n",
      "  4.18213795e-03  4.49189150e-02 -3.13373927e-02 -1.03061311e-02\n",
      "  1.71698365e-02 -1.91278724e-02  3.66394649e-02 -1.09811041e-02\n",
      " -2.78103283e-02 -4.33625282e-03 -2.84797869e-02 -1.90768560e-02\n",
      "  3.84120948e-03  3.57377358e-02  1.14021893e-02 -9.44906650e-03\n",
      "  4.62456930e-02 -2.15416450e-02  1.41789442e-02 -3.67453698e-02\n",
      "  1.59724321e-02 -4.39095187e-03  4.15282531e-02 -2.59159935e-02\n",
      "  8.36245054e-03 -5.18137463e-05  4.38238712e-02  2.55419435e-03\n",
      " -2.21219605e-02  2.14397999e-02  3.38626767e-02 -1.20136738e-03\n",
      "  2.77180098e-02 -6.46673231e-02 -3.70198352e-02 -4.05308064e-03\n",
      "  4.16156367e-03  6.12148804e-02 -2.43080390e-02 -9.70887991e-03\n",
      "  3.91019232e-02  1.53040715e-02 -3.31439308e-02  3.03954334e-03\n",
      "  1.16831456e-02  3.60236045e-03  2.78042364e-02 -2.72550852e-02\n",
      " -1.72338344e-02  4.08342218e-03  1.23376756e-02 -1.43291395e-02\n",
      " -4.49739773e-02  6.51477237e-02 -3.32138668e-02 -3.07543587e-02\n",
      "  8.76963926e-02 -1.78181790e-02 -2.89580328e-02  2.15799152e-02\n",
      " -2.60684926e-02 -6.18870364e-03  6.38208006e-02 -6.15507586e-03\n",
      " -8.53987027e-03  5.29009609e-02 -5.47446594e-02  4.09576466e-02\n",
      "  6.40216676e-03  5.53630105e-02 -4.02110720e-04 -1.00494156e-02\n",
      " -7.52556532e-03  1.91252352e-02 -6.40057042e-03 -9.43205461e-03\n",
      " -7.35882807e-03 -2.08604508e-02  1.21336794e-02 -4.53348142e-02\n",
      " -2.47480408e-02 -3.64027837e-02 -4.48614768e-02  3.17299990e-04\n",
      " -1.98046569e-02  2.20884665e-02 -1.88684492e-02 -2.12415805e-02\n",
      " -1.53419523e-02  4.35725903e-02  1.24545730e-02  1.25751298e-02\n",
      " -4.36875690e-02 -2.18575480e-02 -4.42481963e-02 -1.22168062e-02\n",
      " -2.67783364e-02  7.22166393e-02 -8.32853597e-03 -4.49994109e-02\n",
      " -1.31770103e-02 -1.66823237e-02  1.23143023e-02  1.64652377e-02\n",
      " -1.97272533e-02 -1.70035466e-02  1.50042691e-02 -4.06526999e-02\n",
      " -2.92415924e-03 -5.62605061e-02 -7.45043001e-03  4.81347393e-02\n",
      " -2.48553126e-03 -4.07421238e-02  1.04732200e-02 -2.37658524e-02\n",
      "  8.27368719e-04  3.13645889e-02  8.07168405e-02 -3.48529623e-03\n",
      "  2.31175938e-02  9.48344741e-04 -1.28977845e-02 -5.22393166e-02\n",
      " -1.22280471e-02 -1.49310318e-02  6.92061721e-03  5.51851947e-02\n",
      "  2.47675018e-02  4.79156344e-02 -2.22935618e-02 -1.73795905e-02\n",
      "  6.05398535e-03  9.10539718e-03 -6.13325399e-03  1.15744435e-02\n",
      "  3.31710564e-02 -2.15637476e-02 -2.57185996e-02 -3.37789863e-02\n",
      " -4.06144898e-02 -2.71696383e-02  1.35552204e-02  1.85984286e-02\n",
      " -2.49592090e-02  2.45050032e-02 -1.67157752e-02  3.21947839e-02\n",
      "  8.95287674e-03  1.29017637e-02  7.38651171e-02 -1.87448118e-02\n",
      "  2.74120537e-02 -3.43123620e-02 -8.26965461e-02  5.53806218e-02\n",
      "  4.17991314e-02 -2.20954061e-02 -2.96722349e-03  2.08460501e-02\n",
      "  4.93936305e-02  2.20116505e-02 -1.03016668e-02  1.74698127e-02\n",
      " -1.29415107e-02  2.82611570e-02 -1.12778416e-02  2.85378201e-02\n",
      " -4.73156804e-03  1.05401332e-01 -5.33884236e-02  5.37069454e-03\n",
      " -2.87527103e-02  5.12912521e-02 -9.76118679e-03  2.81733589e-04\n",
      "  6.69863576e-03  1.97262055e-02  6.19911804e-02  6.13235363e-02\n",
      "  1.23772452e-02 -4.26883836e-02 -1.57414280e-02 -5.37248551e-02\n",
      " -1.88323526e-02  2.35901979e-02  3.35094758e-02 -2.42635106e-02\n",
      " -2.48055805e-02 -3.92346295e-02 -6.83295563e-04  2.52904374e-02\n",
      "  4.99027018e-03 -2.23988241e-03 -8.06507612e-02 -2.00932167e-02\n",
      "  5.16348154e-03  6.03308593e-02  1.48988816e-03 -2.11674946e-02\n",
      "  1.65454542e-02 -5.65778222e-02 -8.66092953e-03 -1.55025858e-02\n",
      "  1.25765073e-02 -2.15436995e-02 -2.06500342e-02 -5.98045895e-02\n",
      " -1.89378275e-02  5.85781157e-02  4.29573810e-02  6.99808013e-03\n",
      " -5.41211194e-02  2.09057906e-03 -2.47383374e-02  2.11156587e-02\n",
      " -1.74447863e-02  3.56490034e-02 -2.94186148e-02 -1.79669491e-02\n",
      "  5.25899673e-02  3.45966604e-02  4.57470667e-02 -6.43021594e-02\n",
      "  4.15587921e-02  8.25059617e-03  2.02006153e-03  1.42298800e-02\n",
      " -5.17393149e-03  1.15933752e-02  1.36728820e-02 -5.21558000e-02\n",
      " -5.09437011e-02  7.98611848e-02 -1.47852488e-03  2.74735698e-02\n",
      " -9.72090361e-03]\n"
     ]
    }
   ],
   "source": [
    "#简单处理一下输入的矩阵\n",
    "n = A.shape[1]#获得A的行数\n",
    "X=np.zeros(n+1)#创建一个全0列表，用于存储参数值\n",
    "A=np.hstack((np.ones((A.shape[0],1)),A))# 在A的左侧生成一列全一的列\n",
    "lr=1e-7#学习率\n",
    "td=1e-5#精度\n",
    "X=train(A,b,X,lr,td)\n",
    "print(X)\n",
    "# 由于迭代次数较多，所需要的运行时间较长，如果要重新运行，请耐心等待,可能需要几分钟，如果感觉等着难受的话，可以把train中的那一条注释给取消"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3.在线性回归模型中加入L2-正则化项 ，实现计算过程。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 梯度下降法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 236,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 237,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(50, 500)\n",
      "(50, 1)\n"
     ]
    }
   ],
   "source": [
    "A=np.array(pd.read_csv('randn_data_regression_A.csv',header=None))# 读取randn_data_regression_A.csv中的所有值，并保存为np.array格式\n",
    "b=np.array(pd.read_csv('randn_data_regression_b.csv',header=None))# 读取randn_data_regression_b.csv中的所有值，并保存为np.array格式\n",
    "print(A.shape)\n",
    "print(b.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 241,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loss_s(A,b,X):\n",
    "    loss=np.sum((np.dot(A,X)-b)**2)\n",
    "    return loss/(A.shape[1]*2)\n",
    "\n",
    "def gradient(A,b,X):#计算梯度方向\n",
    "    grad=np.empty(len(X))#新建一个和X长度相等的空np数组\n",
    "    grad[0]=np.sum(A.dot(X)-b)\n",
    "    for i in range(1,len(X)):\n",
    "        grad[i]=(((A.dot(X)-b).dot(A[:,i]))[0])\n",
    "    return grad\n",
    "\n",
    "#梯度下降法求参数\n",
    "def train(A,b,X,lr,td,a):\n",
    "    x = []\n",
    "    y = []\n",
    "    plt.ion()\n",
    "    epoch=0\n",
    "    while 1+1==2:\n",
    "        last_X=X\n",
    "        grad=gradient(A,b,X)+a*X\n",
    "        X=X-lr*grad\n",
    "        #绘图\n",
    "        x.append(epoch)\n",
    "        y.append(abs(loss_s(A,b,X)-loss_s(A,b,last_X)))# \n",
    "#         print(f\"epoch {epoch}:精度为：{abs(loss_s(A,b,X)-loss_s(A,b,last_X))}\")\n",
    "        if abs(loss_s(A,b,X)-loss_s(A,b,last_X))<td:\n",
    "            print(f\"迭代总次数为{epoch}\")\n",
    "            break\n",
    "        elif epoch>3000 or loss_s(A,b,X)>loss_s(A,b,last_X):\n",
    "            print(\"该函数无法收敛！\")\n",
    "            break\n",
    "        epoch+=1\n",
    "    plt.plot(x, y)  # 画出当前x列表和y列表中的值的图形\n",
    "    plt.show()\n",
    "    return X\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 242,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "迭代总次数为1818\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAD4CAYAAADlwTGnAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3deXhV5bn+8e9DRqYwhDCDjCLggBDCJIqiCE6IWgEHUFHUYqu17XX0nNNzWn+ng23V1ooDOAFVEbVUtFWkgnVgkERAZgkIEsYwh5mE5/dHFm2MCWwgycrOvj/Xta+s/e53rf2sFdh39rsmc3dERCT2VAu7ABERCYcCQEQkRikARERilAJARCRGKQBERGJUfNgFnIwGDRp4q1atwi5DRCSqZGVlbXP3tOLtURUArVq1IjMzM+wyRESiipmtK6ldQ0AiIjFKASAiEqMUACIiMUoBICISoxQAIiIxSgEgIhKjFAAiIjEqJgJg8uffMGvl1rDLEBGpVKp8ABwpOMqkuev4wasLWLk5L+xyREQqjSofAAlx1Xh+ZDo1EuMYNWE+2/YeCrskEZFKocoHAECTOtUZPyKd3LxD3DMpi0P5BWGXJCISupgIAIDzWtTl8Ru7kLluJw+/tRjdClNEYl3MBADAlec24ceXnclfFmzg6Y9Wh12OiEioIgoAMxtoZivNLNvMHirh9SQzez14fZ6ZtQraM8xsYfBYZGZDisyz1swWB69V2CU+77ukHdd2acrvpq/kvcWbKuptRUQqnRNeDtrM4oCxwGVADjDfzKa5+7Ii3UYBO929nZkNAx4FhgJLgHR3zzezJsAiM3vH3fOD+S52921luUInYmb85vpz+WbHfn40ZSHN69XgnOZ1KrIEEZFKIZJvABlAtruvcffDwGRgcLE+g4EJwfSbQH8zM3ffX+TDPhmoFAPvyQlxPHdrOqk1k7hz4nw27z4YdkkiIhUukgBoBqwv8jwnaCuxT/CBvxtIBTCzHma2FFgM3FMkEBz4wMyyzGx0aW9uZqPNLNPMMnNzcyNZp4ik1U7ihdvS2Xswnzsnzmf/4fwTzyQiUoVEEgBWQlvxv+RL7ePu89y9M9AdeNjMkoPX+7h7V2AQMMbMLizpzd19nLunu3t6Wtp37mh2Ws5qnMKfbjqfZRv38KPXF1JwtFJ8QRERqRCRBEAO0KLI8+bAxtL6mFk8UAfYUbSDuy8H9gFnB883Bj+3AlMpHGqqcJec1YifXdWJ6Uu38Mu/LQ+jBBGRUEQSAPOB9mbW2swSgWHAtGJ9pgEjg+kbgJnu7sE88QBmdgbQAVhrZjXNrHbQXhMYQOEO41Dc3qc1t/dpxYuffc1Ln30dVhkiIhXqhEcBBUfw3AdMB+KAF919qZk9AmS6+zTgBWCSmWVT+Jf/sGD2C4CHzOwIcBT4vrtvM7M2wFQzO1bDq+7+flmv3Mn47ys7sXHXAR55dxlN61bn8s6NwyxHRKTcWTSdEZuenu6ZmeV3ysCBwwUMHz+X5Zv2MHl0T85vWa/c3ktEpKKYWZa7pxdvj6kzgU+kemIcz49Mp1FKMndOyGTd9n1hlyQiUm4UAMU0qJXEy7d3p8Cd21+az859h8MuSUSkXCgAStAmrRbjR6STs+sAoydlcvCIrh4qIlWPAqAU3VvV57Hvncf8tTv58RuLOKpzBESkijnhUUCx7OrzmrJx1wF+/d4KmtetzsNXdAy7JBGRMqMAOIHRF7YhZ+cBnvt4DY1SkrnjgtZhlyQiUiYUACdgZvz8ms7k5h3ikXeX0aB2Etec1zTsskRETpv2AUQgrprxh2FdyGhdnx9PWcgnq8ruonQiImFRAEQoOSGO8SPSaZtWi3smZbE4Z3fYJYmInBYFwEmoUz2BCXdkULdGIre99Dlrt+lEMRGJXgqAk9QoJZmJozI46s6IFz9na55uJiMi0UkBcAraptXipdszyM07xG0vzifv4JGwSxIROWkKgFPUpUVdnrmlK19tyePuSVkcytfZwiISXRQAp6Ffh4b89oZzmb16Ow++vkh3FBORqKLzAE7TdV2bs33vYX759+WkVE/gV0POJrjPgYhIpaYAKAN3XdiGnfsP8/RHq0lJjuehQWcpBESk0lMAlJGfXt6BPQeP8NzHa0ipnsCYi9uFXZKIyHEpAMqImfHINWeTdzCf301fSUpyPLf2ahV2WSIipYpoJ7CZDTSzlWaWbWYPlfB6kpm9Hrw+z8xaBe0ZZrYweCwysyGRLjMaVatm/P5753Fpx0b87O2lTF2QE3ZJIiKlOmEAmFkcMBYYBHQChptZp2LdRgE73b0d8ATwaNC+BEh39y7AQOA5M4uPcJlRKSGuGk/ddD692qTykze+ZMayLWGXJCJSoki+AWQA2e6+xt0PA5OBwcX6DAYmBNNvAv3NzNx9v7vnB+3JwLHjJCNZZtRKTohj/Mh0zm5WhzGvfsHs7G1hlyQi8h2RBEAzYH2R5zlBW4l9gg/83UAqgJn1MLOlwGLgnuD1SJYZ1WolxTPh9u60Tq3JnRMzWfDNzrBLEhH5lkgCoKTjGYuf8VRqH3ef5+6dge7Aw2aWHOEyCxdsNtrMMs0sMzc3ui7DXLdGIpNGZdCgVhK3vTSf5Zv2hF2SiMi/RBIAOUCLIs+bAxtL62Nm8UAdYEfRDu6+HNgHnB3hMo/NN87d0909PS0tLYJyK5eGKcm8cmcPqifEccvz81i1JS/skkREgMgCYD7Q3sxam1kiMAyYVqzPNGBkMH0DMNPdPZgnHsDMzgA6AGsjXGaV0aJ+DV69qwfVqhk3PT+PNbl7wy5JROTEARCM2d8HTAeWA1PcfamZPWJm1wTdXgBSzSwbeBA4dljnBcAiM1sITAW+7+7bSltmWa5YZdMmrRav3tmDo0edm8bPY9123UtARMJl7tFzAbP09HTPzMwMu4zTsnzTHoaPn0vNxHhev7snzevVCLskEanizCzL3dOLt+tqoBWsY5MU/jyqB3kHj3DT+Hls2n0g7JJEJEYpAEJwdrM6TBzVgx37DnPz+Hls3aO7iolIxVMAhKRLi7pMuKM7m/cc5Kbn57Ft76GwSxKRGKMACFG3M+rz4m3dydm5n1uen8fOfYfDLklEYogCIGQ926Ty/IjurNm2j5sVAiJSgRQAlcAF7RswfkQ62bl7uen5eexQCIhIBVAAVBIXnZnGCyPTWZO7l5vGz2W79gmISDlTAFQifdun8eJt3Vm7fR/Dx8/VjmERKVcKgEqmT7sGvHhbd9bvOMDwcXPJzVMIiEj5UABUQr3bNuCl27uzYdcBho2bo/MERKRcKAAqqZ5tUnn59gw27T7IsHFz2aIQEJEypgCoxDJa12fiHRls2VMYApt3KwREpOwoACq59Fb1mTgqg9y8QwwdN4ecnfvDLklEqggFQBTodkZ9Jo3KYOe+w9z47By+3qZLSYvI6VMARInzW9bjtdE9OZh/lBufm8PKzbqzmIicHgVAFOnctA5T7u5JNYOh4+awOGd32CWJSBRTAESZdg1r88bdvamVFM9N4+cyf+2OE88kIlICBUAUaplagzfu6UVa7SRGvPA5n67aFnZJIhKFFABRqkmd6rx+dy/OSK3BHS/PZ8ayLWGXJCJRJqIAMLOBZrbSzLLN7KESXk8ys9eD1+eZWaug/TIzyzKzxcHPS4rM81GwzIXBo2FZrVSsSKudxOTRPenYNIV7/pzFtEUbwy5JRKLICQPAzOKAscAgoBMw3Mw6Fes2Ctjp7u2AJ4BHg/ZtwNXufg4wEphUbL6b3b1L8Nh6GusRs+rWSOTPozLodkY97p+8gNc+/ybskkQkSkTyDSADyHb3Ne5+GJgMDC7WZzAwIZh+E+hvZubuC9z92J+lS4FkM0sqi8Ll32onJzDh9gwuOjONh/+ymLGzsnH3sMsSkUoukgBoBqwv8jwnaCuxj7vnA7uB1GJ9rgcWuHvRy1u+FAz//MzMrKQ3N7PRZpZpZpm5ubkRlBubqifGMX5EOoO7NOV301fy/95dztGjCgERKV18BH1K+mAu/sly3D5m1pnCYaEBRV6/2d03mFlt4C3gVmDidxbiPg4YB5Cenq5PtONIiKvGEzd2oV6NRF787Gt27j/Mb284l4Q47esXke+K5JMhB2hR5HlzoPjexn/1MbN4oA6wI3jeHJgKjHD31cdmcPcNwc884FUKh5rkNFWrZvzv1Z34yYAzmbpgA3dPyuLA4YKwyxKRSiiSAJgPtDez1maWCAwDphXrM43CnbwANwAz3d3NrC7wN+Bhd//sWGczizezBsF0AnAVsOT0VkWOMTPuu6Q9vxxyNrNWbuWWF+axe/+RsMsSkUrmhAEQjOnfB0wHlgNT3H2pmT1iZtcE3V4AUs0sG3gQOHao6H1AO+BnxQ73TAKmm9mXwEJgAzC+LFdM4OYeZzD2pq4sztnNjc/N0eWkReRbLJqOFklPT/fMzMywy4g6s7O3cdfEzMJDRu/sQesGNcMuSUQqkJlluXt68XbtHYwBvds14LXRPTlwpIAbnpnNwvW7wi5JRCoBBUCMOLd5Xd68pxc1kuIYNm4O/9ClI0RingIghrRJq8Vf7u3DmY1qM3pSJn+euy7skkQkRAqAGHPs+kH9OjTkv/+6hN++v0JnDYvEKAVADKqRGM+4W7sxPKMlT3+0mgenLOJw/tGwyxKRChbJmcBSBcXHVeNXQ86meb3q/G76SrbmHeSZW7qRkpwQdmkiUkH0DSCGmRljLm7H4zeex7w1O7jx2Tls2n0g7LJEpIIoAITrujbn5dszyNl5gCFjZ7N8056wSxKRCqAAEAAuaN+AKXf3AuCGZ2Yza4VuzyBS1SkA5F86NU3hr2P60KpBTUZNmM/Ln30ddkkiUo4UAPItjesk88Y9vbi0YyN+/s4y/uftJeQX6AghkapIASDfUSMxnmdv6cbdF7Zh4px13DEhkz0HdTVRkapGASAlqlbNePiKjvzmunOYnb2N65+ezfod+8MuS0TKkAJAjmtYRksm3pHBlj0HuXbsZ2St2xl2SSJSRhQAckK92zVg6pg+1EqOZ/j4uby9cEPYJYlIGVAASETaptXir9/vQ5cWdbl/8kJ+P32lbjovEuUUABKxejUTmTQqg6HpLXhqVjajJ2WSp53DIlFLASAnJSk+jt9cfw6/uKYzs1bmMuTp2Xy9bV/YZYnIKYgoAMxsoJmtNLNsM3uohNeTzOz14PV5ZtYqaL/MzLLMbHHw85Ii83QL2rPN7Ekzs7JaKSlfZsbI3q2YdEcG2/ceYvBTn/LxV7lhlyUiJ+mEAWBmccBYYBDQCRhuZp2KdRsF7HT3dsATwKNB+zbganc/BxgJTCoyzzPAaKB98Bh4GushIejdrgHT7ruApnWrc9tLn/P8J2t0bwGRKBLJN4AMINvd17j7YWAyMLhYn8HAhGD6TaC/mZm7L3D3jUH7UiA5+LbQBEhx9zle+IkxEbj2tNdGKlyL+jV4697eXNapEf/3t+X8+I1FHDxSEHZZIhKBSAKgGbC+yPOcoK3EPu6eD+wGUov1uR5Y4O6Hgv45J1gmAGY22swyzSwzN1fDDJVRzaR4nrm5Gz+69Ez+8sUGho6by5Y9B8MuS0ROIJIAKGlsvvj3/OP2MbPOFA4L3X0SyyxsdB/n7ununp6WlhZBuRKGatWM+y9tz7O3dGPVljyu+tOnzF+7I+yyROQ4IgmAHKBFkefNgY2l9TGzeKAOsCN43hyYCoxw99VF+jc/wTIlCg08uzFTv9+HmolxDB83l5c++1r7BUQqqUgCYD7Q3sxam1kiMAyYVqzPNAp38gLcAMx0dzezusDfgIfd/bNjnd19E5BnZj2Do39GAG+f5rpIJdGhcW2m/eAC+nVoyC/eWcb9kxey/3B+2GWJSDEnDIBgTP8+YDqwHJji7kvN7BEzuybo9gKQambZwIPAsUNF7wPaAT8zs4XBo2Hw2r3A80A2sBp4r6xWSsKXkpzAuFu78dPLO/DulxsZMlbnC4hUNhZNX8/T09M9MzMz7DLkJH2yKpcfvraA/ALnsRvPY0DnxmGXJBJTzCzL3dOLt+tMYCl3fdun8c4PLqB1Wk1GT8rid9NXUKDrCImETgEgFaJ5vRpMubsXwzNaMHbWam576XN27DscdlkiMU0BIBUmOSGOX193Lo9efw7zvt7BlU9+QtY6HSoqEhYFgFS4od1b8tY9vUmIq8bQ5+Yy7uPVurS0SAgUABKKc5rX4d0fXsBlnRrxq7+v4K6JmezUkJBIhVIASGhSkhN4+uau/OKaznyyalswJKRbTopUFAWAhOrYpaXfvLcXcXHG0OfmaEhIpIIoAKRSOLd5Xd79QV8NCYlUIAWAVBp1qv97SOjjVbk6SkiknCkApFI5NiT01r29iYszbnxuLn/6cJVOHBMpBwoAqZTObV6Xv/2wL1ed24THZnzF8HFz2bDrQNhliVQpCgCptFKSE/jD0C48fuN5LN24m0F/+Ji/L94UdlkiVYYCQCo1M+O6rs35+/19aZ1Wi++/8gX/8eaXury0SBlQAEhUOCO1Jm/e04sxF7dlStZ6rnryU5Zs2B12WSJRTQEgUSMhrho/vfwsXrmzB/sPFzDk6c8Y//EanTMgcooUABJ1erdtwHv39+XiDg355d+XM+LFz9m0WzuIRU6WAkCiUr2aiTx3azd+NeQcstbtZMATH/PXBRt0/2GRk6AAkKhlZtzUoyXv3d+XMxvV5oHXF3Lfqwt0BrFIhCIKADMbaGYrzSzbzB4q4fUkM3s9eH2embUK2lPNbJaZ7TWzp4rN81GwzOL3ChY5Ka0a1GTK3b346eUd+GDZZgb84WNmrdwadlkild4JA8DM4oCxwCCgEzDczDoV6zYK2Onu7YAngEeD9oPAz4CflLL4m929S/DQ/1g5ZXHVjDEXt+OvY/pQv0Yit780n/+cuph9h3S4qEhpIvkGkAFku/sadz8MTAYGF+szGJgQTL8J9Dczc/d97v4phUEgUu46N63D2/f1YfSFbXjt82+4QtcTEilVJAHQDFhf5HlO0FZiH3fPB3YDqREs+6Vg+OdnZmYldTCz0WaWaWaZubm5ESxSYl1yQhz/eUVHJt/Vk4KjzveencOj76/gUH5B2KWJVCqRBEBJH8zFD7WIpE9xN7v7OUDf4HFrSZ3cfZy7p7t7elpa2gmLFTmmR5tU3ru/L9/r1oJnPlrNlU9+yoJvdMMZkWMiCYAcoEWR582BjaX1MbN4oA5w3O/d7r4h+JkHvErhUJNImaqdnMCjN5zLy7d3Z9+hfK5/Zja//vtyDh7RtwGRSAJgPtDezFqbWSIwDJhWrM80YGQwfQMw049zQLaZxZtZg2A6AbgKWHKyxYtEql+HhnzwowsZ2r0lz328hiv+qH0DIicMgGBM/z5gOrAcmOLuS83sETO7Juj2ApBqZtnAg8C/DhU1s7XA48BtZpYTHEGUBEw3sy+BhcAGYHzZrZbId9VOTuDX153Dn0f14FD+UW54dg6PvLOMA4f1bUBik0XTmZPp6ememZkZdhlSBew9lM+j761g0tx1nJFag0evP5eebSI5bkEk+phZlrunF2/XmcASk2olxfP/rj2b1+7qiTsMGzeX/3l7CXt13oDEEAWAxLRebVN5/4G+3N6nFZPmruOyx//JjGVbwi5LpEIoACTm1UiM53+v7sxb9/YmJTmBuyZmcu+fs9iyR+cvStWmABAJdG1Zj3d/eAE/vbwDH67YyqWP/ZM/z12n+w1IlaUAECkiIa4aYy5ux/QHLuSc5nX4778u4XvPzeGrLXlhlyZS5hQAIiVo3aAmr9zZg8e+dx5rcvdy5ZOf8NgHK3UCmVQpCgCRUpgZ13drzj8evIirz23Kn2ZmM+iPn/BZ9rawSxMpEwoAkRNIrZXE40O7MGlUBkfdufn5efzgtQVs3q2dxBLdFAAiEerbPo3pD1zIA5e2Z/rSzfR/7COe/2QNRwqOhl2ayClRAIichOSEOB649Exm/OhCMlrX5//+tpyrnvyUeWu2h12ayElTAIicgjNSa/Libd0Zd2s39h7KZ+i4uTz4+kJy8w6FXZpIxBQAIqfIzBjQuTH/ePAixlzclne+3Mglj33EhNlrydewkEQBBYDIaaqeGMdPLz+L6Q9cSJcWdfnfaUu55qnP+PxrXW5aKjcFgEgZaZNWi4l3ZDD2pq7s2n+YG5+bw5hXvyBn5/6wSxMpkQJApAyZGVee24QPf9yPBy5tz4fLt9D/sX/y+Iyv2H9YVxqVykUBIFIOqicWHi304Y/7MaBzY578cBX9H/snby/cQDTdg0OqNgWASDlqVrc6fxp+Pm/c04vUWoncP3khNzw7hy9zdoVdmogCQKQidG9Vn7fHXMBvrz+Xddv3MXjsZ/z0jUVs1SWnJUQRBYCZDTSzlWaWbWYPlfB6kpm9Hrw+z8xaBe2pZjbLzPaa2VPF5ulmZouDeZ40MyuLFRKprOKqGTd2b8Gsn/RjdN82/HXhBvr9/iOemPEV+3QnMgnBCQPAzOKAscAgoBMwPLixe1GjgJ3u3g54Ang0aD8I/Az4SQmLfgYYDbQPHgNPZQVEok3t5AQevqIjM350Ef06pPHHD1fR7/cf8drn3+j8AalQkXwDyACy3X2Nux8GJgODi/UZDEwIpt8E+puZufs+d/+UwiD4FzNrAqS4+xwv3CM2Ebj2dFZEJNq0alCTp2/uxlv39qZl/Ro8/JfFDPrjJ8xcsUU7iqVCRBIAzYD1RZ7nBG0l9nH3fGA3kHqCZeacYJkAmNloM8s0s8zc3NwIyhWJLt3OqMeb9/Ti2Vu6cqTgKHe8nMlN4+exZMPusEuTKi6SAChpbL74nyeR9Dml/u4+zt3T3T09LS3tOIsUiV5mxsCzmzDjwYv4xTWdWbklj6v+9CkPTF6gE8mk3EQSADlAiyLPmwMbS+tjZvFAHeB458HnBMs53jJFYk5CXDVG9m7FRz/tx7392vLeks1c8tg/+b93l7F9ry40J2UrkgCYD7Q3s9ZmlggMA6YV6zMNGBlM3wDM9OMMYrr7JiDPzHoGR/+MAN4+6epFqqiU5AT+Y+BZzPpJP645rykvfvY1F/52Fk/M+Iq8g0fCLk+qCItkZ5OZXQH8AYgDXnT3X5rZI0Cmu08zs2RgEnA+hX/5D3P3NcG8a4EUIBHYBQxw92Vmlg68DFQH3gN+cLzQAEhPT/fMzMxTWlGRaJa9NY/HPviK95Zspl6NBL7frx239jqD5IS4sEuTKGBmWe6e/p32aDraQAEgse7LnF38bvpKPlm1jcYpyfywf3u+l96chDid0ymlKy0A9K9GJIqc27wuk0b14LW7etK0bjL/OXUxlz1eeI2ho0ej5485qRwUACJRqFfbVN66tzfPj0gnOSGO+ycv5IonP2H60s06h0AipgAQiVJmxqWdGvH3H/blj8O6cPBIAXdPyuLKJz9VEEhEtA9ApIrILzjK2ws38qeZq1i7fT+dmqTwwKXtuaxTI3SprdimncAiMaJ4EHRumsL9/RUEsUwBIBJjFARyjAJAJEaVFAT3XdyOyzs3plo1BUEsUACIxLj8gqP8deFGngqCoG1aTe7t147BXZrqPIIqTgEgIgAUHHX+vngTY2dls2JzHs3qVufui9pwY3oLnVlcRSkARORb3J1ZK7fy1MxsvvhmFw1qJTLqgjbc0rMltZMTwi5PypACQERK5O7M+3oHY2dl88mqbaQkxzOydytu79Oa+jUTwy5PyoACQERO6MucXTw9azXvL91M9YQ4hnZvwR19WtMytUbYpclpUACISMRWbcnjmX+u5p1FGyk46gw6uwl3XdiGLi3qhl2anAIFgIictM27D/Ly7LW8Mm8deQfzyWhVn7subEP/sxrqENIoogAQkVO291A+r89fz4uffs2GXQdo06Amd/Ztw3Vdm+nIoSigABCR05ZfcJT3lmxm3MdrWLxhN6k1E7m11xnc2vMMUmslhV2elEIBICJl5tiRQ+M/XsOHK7aSGF+Na7s0ZWTvVnRuWifs8qSY0gIgPoxiRCS6mRk926TSs00q2VvzeHn2Wt7K2sCUzBwyWtfn9t6tuKxTI+J1hnGlFuk9gQcCf6TwnsDPu/tvir2eBEwEugHbgaHuvjZ47WFgFFAA/NDdpwfta4G8oD2/pHQqTt8ARCqv3fuP8EbWeibMWcv6HQdoWieZW3u1Ylj3FtTT+QShOuUhIDOLA74CLgNygPnAcHdfVqTP94Fz3f0eMxsGDHH3oWbWCXgNyACaAv8AznT3giAA0t19W6QroQAQqfwKjjozV2zl5dlf81n2dpLiqzHk/GaM7N2Kjk1Swi4vJp3OEFAGkO3ua4IFTQYGA8uK9BkM/DyYfhN4ygqvNzsYmOzuh4CvzSw7WN6cU10REanc4qoZl3VqxGWdGrFycx4T5qzlL1/kMHn+enq0rs+IXoXDQ4nxGh4KWyS/gWbA+iLPc4K2Evu4ez6wG0g9wbwOfGBmWWY2urQ3N7PRZpZpZpm5ubkRlCsilUWHxrX51ZBzmPtwf/7zirPYsOsAY179gt6/mcnvp68kZ+f+sEuMaZF8AyjpbI/i40al9TnevH3cfaOZNQRmmNkKd//4O53dxwHjoHAIKIJ6RaSSqVsjkdEXtmXUBW34+KtcXpm3jqc/ymbsR9lc3KEht/RsyUVnNiROJ5dVqEgCIAdoUeR5c2BjKX1yzCweqAPsON687n7s51Yzm0rh0NB3AkBEqo64asbFZzXk4rMasmHXASZ//g2T56/njpczaVa3OsMzWnBj9xY0rJ0cdqkxIZIhoPlAezNrbWaJwDBgWrE+04CRwfQNwEwv3Ls8DRhmZklm1hpoD3xuZjXNrDaAmdUEBgBLTn91RCRaNKtbnR8P6MDshy7hmZu70qpBDX7/wVf0/vVMxrzyBZ9lb+PoUX3pL08n/Abg7vlmdh8wncLDQF9096Vm9giQ6e7TgBeAScFO3h0UhgRBvykU7jDOB8YERwA1AqYG9yWNB1519/fLYf1EpJJLiKvGoHOaMOicJqzJ3ctrn3/DG1k5/G3xJlrWr8H3ujXn+m7NaVq3etilVjk6E1hEKp2DRwp4f8lmpmSuZ/bq7VQz6Ns+jaHdW6BAUv4AAApESURBVHBpRx1BdLJ0KQgRiUrfbN/PG1nreTMrh027D1K/ZiLXdmnG0O4t6NC4dtjlRQUFgIhEtYKjziercpmSuZ4Zy7ZwpMA5r3kdbuzegqvPa0qKbmNZKgWAiFQZO/YdZuqCDUyZv56VW/JITqjGgE6NGdK1GX3bNdA1iIpRAIhIlePuLMrZzZtZ63ln0SZ2HzhCg1pJXHNeU67r2ozOTVMIDjaJaQoAEanSDuUXMGtFLlMX5DBzxVaOFDhnNqrFkPObc+35TWlSJ3aPIlIAiEjM2LX/MO9+uYm/fJHDF9/swgx6t01lyPnNGXh2Y2olxdaV8BUAIhKT1m7bx9QFG5i6YAPf7NhP9YQ4+ndsyNXnNeWiM9Ni4paWCgARiWnuTta6nUxdsIH3lmxmx77D1E6KZ0Dnxlx9XhP6tGtAQhXdeawAEBEJ5BccZfbq7byzaCPvL91M3sF86tVIYODZTbj6vCb0aJ1apS5MpwAQESnBofwCPv5qG+8s2siMZVs4cKSAtNpJXHlOE64+ryldW9aN+iOJFAAiIiew/3A+M1ds5Z1FG5m1MpfD+UdpWieZAZ0bM+jsxqS3qh+V3wwUACIiJyHv4BE+WLqF95Zs4uNV2zicf5QGtZIY0LkRg85uTM82qVGzz0ABICJyivYeymfWiq28v2Qzs1ZuZf/hAupUT+DSjoVhcEH7BpX6aCIFgIhIGTh4pIB/fpXL9CWbmbF8C3kH86mZGMclHRsxsHNj+nVIo2YlO8/gdG4KLyIigeSEOC7v3JjLOzfmcP5RZq/exvtLNvPBsi28s2gjiXHV6NU2lUs7NeLSjg0r9RnI+gYgIlIG8guOMn/tTj5cvoUZy7ewbnvhDe/PbpZC/7MacVmnRqFdm0hDQCIiFcTdWZ27lxnLtvLh8i1kfbMTd2hSJ5n+HRtyacdG9GqbSlJ8xew3UACIiIRk295DzFqxlX8s38Inq7ax/3ABNRLjuLB9Gpec1ZCLOqTRKCW53N7/tALAzAYCf6TwnsDPu/tvir2eBEwEugHbgaHuvjZ47WFgFFAA/NDdp0eyzJIoAEQk2h08UsCcNdv5x7ItfLh8K5v3HASgU5MU+nVIo1+HhnRtWbdM72lwygFgZnHAV8BlQA4wHxju7suK9Pk+cK6732Nmw4Ah7j7UzDoBrwEZQFPgH8CZwWzHXWZJFAAiUpW4Oys25/HRylw+WrmVzHU7KTjqpCTH07d9Ghd1SKPfmWk0PM1vB6dzFFAGkO3ua4IFTQYGA0U/rAcDPw+m3wSessI9HYOBye5+CPjazLKD5RHBMkVEqjQzo2OTFDo2SeHefm3Zc/AIn63axqyVW/loZS5/W7wJgM5NU5h4RwaptZLK9P0jCYBmwPoiz3OAHqX1cfd8M9sNpAbtc4vN2yyYPtEyATCz0cBogJYtW0ZQrohIdEpJTmDQOU0YdE4T3J3lm/KYtXIri9bvon7NxDJ/v0gCoKRjloqPG5XWp7T2kga3ShyLcvdxwDgoHAIqvUwRkarDzOjUNIVOTVPK7T0i2cuQA7Qo8rw5sLG0PmYWD9QBdhxn3kiWKSIi5SiSAJgPtDez1maWCAwDphXrMw0YGUzfAMz0wr3L04BhZpZkZq2B9sDnES5TRETK0QmHgIIx/fuA6RQesvmiuy81s0eATHefBrwATAp28u6g8AOdoN8UCnfu5gNj3L0AoKRllv3qiYhIaXQimIhIFVfaYaDRcTFrEREpcwoAEZEYpQAQEYlRCgARkRgVVTuBzSwXWHeKszcAtpVhOeVFdZadaKgRVGdZU53fdYa7pxVvjKoAOB1mllnSXvDKRnWWnWioEVRnWVOdkdMQkIhIjFIAiIjEqFgKgHFhFxAh1Vl2oqFGUJ1lTXVGKGb2AYiIyLfF0jcAEREpQgEgIhKjqnwAmNlAM1tpZtlm9lDItbQws1lmttzMlprZ/UH7z81sg5ktDB5XFJnn4aD2lWZ2eQXWutbMFgf1ZAZt9c1shpmtCn7WC9rNzJ4M6vzSzLpWUI0dimyzhWa2x8weqAzb08xeNLOtZrakSNtJbz8zGxn0X2VmI0t6r3Ko83dmtiKoZaqZ1Q3aW5nZgSLb9dki83QL/r1kB+tS0s2gyrrOk/49l+fnQSk1vl6kvrVmtjBoD21bfou7V9kHhZeaXg20ARKBRUCnEOtpAnQNpmsDXwGdKLyf8k9K6N8pqDkJaB2sS1wF1boWaFCs7bfAQ8H0Q8CjwfQVwHsU3gGuJzAvpN/1ZuCMyrA9gQuBrsCSU91+QH1gTfCzXjBdrwLqHADEB9OPFqmzVdF+xZbzOdArWIf3gEEVUOdJ/Z7L+/OgpBqLvf4Y8D9hb8uij6r+DeBfN7R398PAsZvPh8LdN7n7F8F0HrCcf98juSSDgcnufsjdvwayKVynsAwGJgTTE4Bri7RP9EJzgbpm1qSCa+sPrHb3450pXmHb090/pvDeGMXf/2S23+XADHff4e47gRnAwPKu090/cPf84OlcCu/YV6qg1hR3n+OFn2AT+fe6lVudx1Ha77lcPw+OV2PwV/yNwGvHW0ZFbMuiqnoAlHRD++N94FYYM2sFnA/MC5ruC75yv3hsaIBw63fgAzPLMrPRQVsjd98EhWEGNKwEdR4zjG//56ps2xNOfvuFXS/AHRT+FXpMazNbYGb/NLO+QVuzoLZjKrLOk/k9h7k9+wJb3H1VkbbQt2VVD4BIbmhf4cysFvAW8IC77wGeAdoCXYBNFH5VhHDr7+PuXYFBwBgzu/A4fUPdzlZ4W9FrgDeCpsq4PY+ntLrC3q7/ReGd/F4JmjYBLd39fOBB4FUzSyG8Ok/29xzm9hzOt/9AqRTbsqoHQKW7+byZJVD44f+Ku/8FwN23uHuBux8FxvPvYYnQ6nf3jcHPrcDUoKYtx4Z2gp9bw64zMAj4wt23QOXcnoGT3X6h1RvscL4KuDkYiiAYUtkeTGdROJ5+ZlBn0WGiCqnzFH7PoWxPM4sHrgNeP9ZWWbZlVQ+ASnXz+WAc8AVgubs/XqS96Hj5EODYUQTTgGFmlmRmrYH2FO4gKu86a5pZ7WPTFO4UXBLUc+xIlJHA20XqHBEczdIT2H1sqKOCfOuvq8q2PYs42e03HRhgZvWC4Y0BQVu5MrOBwH8A17j7/iLtaWYWF0y3oXD7rQlqzTOznsG/8RFF1q086zzZ33NYnweXAivc/V9DO5VmW5bX3uXK8qDwCIuvKEzY/wq5lgso/Dr3JbAweFwBTAIWB+3TgCZF5vmvoPaVlOPRAMXqbEPhERKLgKXHthuQCnwIrAp+1g/aDRgb1LkYSK/AbVoD2A7UKdIW+vakMJA2AUco/Ktu1KlsPwrH4LODx+0VVGc2hWPlx/6NPhv0vT7497AI+AK4ushy0in8AF4NPEVwlYFyrvOkf8/l+XlQUo1B+8vAPcX6hrYtiz50KQgRkRhV1YeARESkFAoAEZEYpQAQEYlRCgARkRilABARiVEKABGRGKUAEBGJUf8fUyUhGOjRFJcAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 7.09127212e-01  2.01432651e-01  2.01432651e-01  7.64940462e-03\n",
      "  1.15019184e-02 -4.73035918e-02 -4.29191345e-03 -6.46731110e-03\n",
      " -2.49545969e-02 -1.05883016e-02  6.67152947e-03 -3.91448278e-04\n",
      " -5.86144922e-02  3.90830285e-02 -6.65339232e-02  2.18506813e-02\n",
      "  1.11818245e-03 -1.31705142e-02 -9.38811345e-03  2.96028744e-02\n",
      "  1.02791926e-02 -3.87283727e-02 -2.08604612e-02 -2.82979986e-02\n",
      "  3.05045265e-02 -1.66785130e-02 -2.43847384e-02 -1.37371272e-02\n",
      " -1.88317227e-02  1.89243744e-02  4.60124448e-02  2.32977975e-02\n",
      "  3.55948667e-02  2.01911842e-02  4.49976173e-02  6.29787165e-02\n",
      "  1.62594676e-02 -3.09440447e-02 -1.74621752e-03 -8.47122853e-03\n",
      " -2.40186433e-02  4.21028734e-02  5.50547248e-03  4.65641555e-02\n",
      "  4.05170000e-03  9.79555297e-05  5.15712712e-03 -4.70986671e-03\n",
      "  1.45881784e-02  7.47986024e-02 -2.05410842e-02 -6.28550771e-03\n",
      "  3.38935811e-02 -4.42112745e-02  5.52059718e-02  5.15482895e-02\n",
      " -6.06605904e-02 -1.87433502e-02 -1.14157961e-02 -1.73216398e-02\n",
      " -1.20046410e-02  2.29510938e-02 -3.84255101e-02  5.15707843e-03\n",
      " -3.79941731e-03 -6.67233169e-03 -2.54532604e-02  4.10340387e-03\n",
      "  2.74208814e-02  6.84850652e-03  1.38374805e-02  4.80912027e-02\n",
      "  2.31755659e-03 -5.04673435e-02 -1.36826169e-02  2.80383282e-02\n",
      "  3.22793421e-02 -6.61522291e-03 -3.30066739e-02  1.39820504e-02\n",
      "  5.23820607e-03  1.89811388e-02  4.09642150e-02 -3.40848880e-03\n",
      " -1.10358518e-02  7.59721972e-03 -3.71158902e-02 -1.93429050e-02\n",
      "  1.77217523e-02  9.53243997e-03 -8.78984364e-03  2.63630606e-02\n",
      " -4.08195088e-02  2.89150728e-02  8.75463514e-03 -2.75998387e-02\n",
      "  1.41999015e-02 -5.56365823e-03 -7.18064145e-04  3.39380018e-02\n",
      " -2.01369928e-02  1.23354767e-02  4.24483295e-03 -1.69483121e-02\n",
      "  2.49632974e-02 -2.50319576e-02  4.75723865e-02 -3.03489751e-02\n",
      " -4.44081360e-02 -2.50577393e-03  6.52653030e-04 -6.19740772e-02\n",
      "  6.08690671e-02 -9.31024640e-03 -1.74731268e-02  2.83792216e-02\n",
      " -1.91867781e-02 -6.29029073e-02 -1.89653552e-03  6.43267963e-02\n",
      "  2.90174718e-02  6.08145046e-03 -3.19636454e-02 -1.39292664e-02\n",
      " -3.07294024e-02  3.63710801e-02  4.96680769e-02  1.30834838e-02\n",
      "  6.06707607e-03 -4.72968010e-02  8.64050914e-03 -1.05884988e-02\n",
      "  5.82382760e-02  1.72889776e-02  5.19771850e-03 -6.29204312e-02\n",
      "  1.10822450e-02  6.40769527e-03  9.57355710e-03 -1.60595446e-02\n",
      " -4.56091684e-02 -2.25183218e-02 -4.63445904e-04  1.38113321e-02\n",
      " -1.37804156e-02 -2.82106913e-02 -7.42774053e-03 -4.76593761e-02\n",
      " -3.27845331e-02  1.41363621e-02  8.63543114e-03 -1.44957635e-02\n",
      " -5.08091471e-02 -1.59813644e-03  2.62822891e-02  4.73345957e-02\n",
      "  2.88123101e-02 -2.17461236e-02  1.45779066e-02 -1.69155437e-02\n",
      "  3.00901376e-02  1.39511289e-02  4.15181284e-02 -2.46579036e-02\n",
      " -1.95961622e-02  2.04207682e-02  1.50878243e-02 -9.56457810e-03\n",
      " -5.06496506e-02 -2.08519920e-02  2.41913895e-02 -1.43196341e-02\n",
      "  1.52960650e-02  2.26431998e-03 -2.69400765e-02  6.95205075e-02\n",
      "  7.04710593e-02 -4.00314824e-02 -2.72388692e-02 -3.18619532e-02\n",
      " -8.96659806e-03  2.38615744e-02 -3.83397854e-02  4.62664231e-02\n",
      "  1.76255681e-02  4.80181240e-02  6.09697195e-03  2.51208883e-02\n",
      " -3.60092115e-02  2.10802784e-02 -1.09762565e-02 -4.00881200e-03\n",
      " -2.26747457e-02 -1.05371654e-02  3.33659837e-02 -5.35146223e-02\n",
      "  2.43458832e-02 -7.17455480e-02 -1.53448268e-02  2.33908235e-02\n",
      " -2.52978178e-02  4.34905017e-02 -1.05604899e-02 -1.21834902e-03\n",
      "  3.84671969e-02  2.94360034e-03 -5.53712653e-03 -1.63213822e-02\n",
      " -7.01009161e-03  5.97685899e-03  3.94860820e-02  1.48758132e-02\n",
      "  1.28742126e-02  1.49501717e-02  2.13515019e-02 -3.33983453e-03\n",
      "  5.67363252e-03 -5.33796043e-03  4.86981071e-02 -2.09745929e-02\n",
      "  2.91714336e-03  4.49788672e-02 -2.37970167e-03 -3.32777291e-02\n",
      "  2.42354254e-03 -7.59065776e-03 -7.90299945e-03  3.12596103e-02\n",
      "  3.78954277e-02  2.09451957e-02 -1.75717042e-03  1.66641598e-02\n",
      "  3.28013255e-02  2.57116049e-02 -9.73935766e-03 -2.53074005e-02\n",
      "  4.86955828e-03 -6.51172145e-03  1.79517617e-02  8.16872024e-03\n",
      " -3.05458173e-02 -9.35287789e-03  1.64468224e-03  1.60395191e-02\n",
      " -8.04047517e-03 -3.98783241e-02 -2.59171048e-02 -1.98330333e-02\n",
      "  1.90039796e-02 -2.21659375e-02  2.39391557e-04  1.89461570e-02\n",
      "  2.59548291e-02  1.21807812e-02 -1.09680970e-02  2.00773153e-02\n",
      "  3.85267017e-02  3.53617648e-02 -1.38283196e-02  2.00807893e-02\n",
      "  9.00723696e-03 -2.28428905e-02 -2.08975639e-02 -1.30819168e-02\n",
      " -3.21476126e-03  5.97923271e-03  3.75031448e-03  3.94944074e-02\n",
      " -2.76177417e-02 -9.02288578e-03  1.51236151e-02 -1.68476168e-02\n",
      "  3.21914022e-02 -9.65252230e-03 -2.45059276e-02 -3.89897556e-03\n",
      " -2.49914063e-02 -1.68083634e-02  3.42690589e-03  3.15173211e-02\n",
      "  9.98154800e-03 -8.27624307e-03  4.07163537e-02 -1.89679129e-02\n",
      "  1.25182230e-02 -3.23559661e-02  1.40375484e-02 -3.83487038e-03\n",
      "  3.64806016e-02 -2.27435362e-02  7.35753499e-03 -1.03145992e-05\n",
      "  3.85240276e-02  2.22242466e-03 -1.94537480e-02  1.89043904e-02\n",
      "  2.97199697e-02 -1.05726520e-03  2.42777960e-02 -5.68380813e-02\n",
      " -3.25868253e-02 -3.62077699e-03  3.57221426e-03  5.38762205e-02\n",
      " -2.13436570e-02 -8.60707869e-03  3.43714879e-02  1.33860240e-02\n",
      " -2.91730451e-02  2.71032176e-03  1.03054582e-02  3.15809428e-03\n",
      "  2.45004019e-02 -2.39113228e-02 -1.52880016e-02  3.59021957e-03\n",
      "  1.08069434e-02 -1.26102638e-02 -3.94311280e-02  5.72583657e-02\n",
      " -2.92674341e-02 -2.69229488e-02  7.69896186e-02 -1.56917083e-02\n",
      " -2.53952476e-02  1.90099422e-02 -2.30075933e-02 -5.50254610e-03\n",
      "  5.61210516e-02 -5.43184722e-03 -7.55464120e-03  4.66232544e-02\n",
      " -4.82350588e-02  3.59880158e-02  5.63964884e-03  4.86552928e-02\n",
      " -3.37950461e-04 -8.79003788e-03 -6.60564639e-03  1.68336763e-02\n",
      " -5.70023272e-03 -8.23158149e-03 -6.46313718e-03 -1.83445585e-02\n",
      "  1.06821661e-02 -3.98305940e-02 -2.17936826e-02 -3.19302451e-02\n",
      " -3.94215340e-02  2.82974233e-04 -1.74634201e-02  1.94387584e-02\n",
      " -1.66235744e-02 -1.86406005e-02 -1.34318964e-02  3.82756650e-02\n",
      "  1.09799823e-02  1.10310285e-02 -3.85458131e-02 -1.91103689e-02\n",
      " -3.89106102e-02 -1.06728079e-02 -2.35393336e-02  6.35295974e-02\n",
      " -7.26658357e-03 -3.96275366e-02 -1.15395614e-02 -1.46586864e-02\n",
      "  1.08155868e-02  1.44077477e-02 -1.74478174e-02 -1.50311195e-02\n",
      "  1.31738071e-02 -3.57789563e-02 -2.59002483e-03 -4.94733161e-02\n",
      " -6.54098928e-03  4.23421143e-02 -2.21235888e-03 -3.58467050e-02\n",
      "  9.21984609e-03 -2.09287147e-02  6.62346617e-04  2.75810660e-02\n",
      "  7.09871532e-02 -2.98710417e-03  2.03103478e-02  8.60880026e-04\n",
      " -1.13512911e-02 -4.58720249e-02 -1.07360096e-02 -1.30599246e-02\n",
      "  6.00891427e-03  4.84955309e-02  2.17969143e-02  4.21338002e-02\n",
      " -1.95431592e-02 -1.53062502e-02  5.43752261e-03  7.96942618e-03\n",
      " -5.35118496e-03  1.01377192e-02  2.91655654e-02 -1.89384841e-02\n",
      " -2.26353557e-02 -2.97503045e-02 -3.56499249e-02 -2.38880368e-02\n",
      "  1.19347268e-02  1.63971345e-02 -2.19756156e-02  2.15406410e-02\n",
      " -1.47577341e-02  2.83958877e-02  7.83800093e-03  1.14166717e-02\n",
      "  6.49313970e-02 -1.64718609e-02  2.40446508e-02 -3.01541364e-02\n",
      " -7.26923178e-02  4.86239055e-02  3.67584953e-02 -1.95020786e-02\n",
      " -2.59477354e-03  1.84198372e-02  4.34363454e-02  1.93184877e-02\n",
      " -9.17422425e-03  1.53425890e-02 -1.13900232e-02  2.48823773e-02\n",
      " -1.00452419e-02  2.50483691e-02 -4.18553218e-03  9.27888368e-02\n",
      " -4.68464766e-02  4.62252719e-03 -2.53010670e-02  4.51720424e-02\n",
      " -8.67969381e-03  1.76742518e-04  5.87982758e-03  1.73219641e-02\n",
      "  5.45637033e-02  5.40271029e-02  1.09080063e-02 -3.76523800e-02\n",
      " -1.39332613e-02 -4.72844132e-02 -1.65394074e-02  2.07555363e-02\n",
      "  2.95379251e-02 -2.13327151e-02 -2.19362624e-02 -3.45144445e-02\n",
      " -5.47614526e-04  2.22671904e-02  4.43532846e-03 -1.98417622e-03\n",
      " -7.09095957e-02 -1.76662827e-02  4.59401564e-03  5.30481590e-02\n",
      "  1.26488491e-03 -1.85805116e-02  1.45491138e-02 -4.97798682e-02\n",
      " -7.53967779e-03 -1.36502677e-02  1.09938616e-02 -1.89268182e-02\n",
      " -1.81379004e-02 -5.26582967e-02 -1.67052024e-02  5.15285130e-02\n",
      "  3.77269327e-02  6.22322853e-03 -4.75913485e-02  1.80765585e-03\n",
      " -2.17240215e-02  1.85325206e-02 -1.52901022e-02  3.14024364e-02\n",
      " -2.59119541e-02 -1.57645568e-02  4.62642089e-02  3.03089689e-02\n",
      "  4.01577146e-02 -5.66239914e-02  3.65360887e-02  7.22220937e-03\n",
      "  1.78385080e-03  1.25610767e-02 -4.53239123e-03  1.01573008e-02\n",
      "  1.20650136e-02 -4.58990486e-02 -4.48092587e-02  7.03565253e-02\n",
      " -1.26854380e-03  2.41049371e-02 -8.54204978e-03]\n"
     ]
    }
   ],
   "source": [
    "n = A.shape[1]#获得A的行数\n",
    "X=np.zeros(n+1)#创建一个全0列表，用于存储参数值\n",
    "A=np.hstack((np.ones((A.shape[0],1)),A))# 在A的左侧生成一列全一的列\n",
    "lr=1e-7#学习率\n",
    "td=1e-4#精度\n",
    "a=20\n",
    "X=train(A,b,X,lr,td,a)\n",
    "print(X)\n",
    "# 由于迭代次数较多，所需要的运行时间较长，如果要重新运行，请耐心等待,可能需要几分钟，如果感觉等着难受的话，可以把train中的那一条注释给取消"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 最小二乘法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 244,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(50, 500)\n",
      "(50, 1)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "A=np.array(pd.read_csv('randn_data_regression_A.csv',header=None))# 读取randn_data_regression_A.csv中的所有值，并保存为np.array格式\n",
    "b=np.array(pd.read_csv('randn_data_regression_b.csv',header=None))# 读取randn_data_regression_b.csv中的所有值，并保存为np.array格式\n",
    "print(A.shape)\n",
    "print(b.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 247,
   "metadata": {},
   "outputs": [],
   "source": [
    "def linear_equation(A,b,a):# 解线性方程组法求解线性回归模型参数\n",
    "    n = A.shape[1]#获得A的行数\n",
    "    X=np.zeros(n)#创建一个全0列表，用于存储参数值\n",
    "    A=np.hstack((np.ones((50,1)),A))# 在A的左侧生成一列全一的列\n",
    "    X=np.dot(np.dot(np.linalg.inv(np.dot(A.T,A))+np.eye(n+1) * a * A.shape[0],A.T),b)#公式求解参数\n",
    "    return X.T\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 248,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 501)\n",
      "[[ 1.64845957e+05  2.10568964e+04  1.66047515e+04  8.18676639e+04\n",
      "   3.25363210e+05  4.49268864e+05 -1.11129508e+05 -9.83737663e+04\n",
      "   3.93116029e+05  1.14793325e+05 -3.01933348e+05  3.30819829e+04\n",
      "   4.04473671e+04  2.36139817e+05 -3.13370541e+04  2.24961656e+05\n",
      "   7.25249765e+04 -1.54072609e+05  2.09877621e+05 -1.27016425e+05\n",
      "   2.67144199e+05  6.98418282e+04  4.19875845e+05  2.71984847e+05\n",
      "  -1.94527165e+05 -4.92289952e+04 -8.57400316e+03  2.28360633e+05\n",
      "   1.13802776e+05  2.69017035e+05  2.38688847e+05  1.69501394e+05\n",
      "   6.96022550e+02  5.93010679e+05  2.07660400e+05 -9.81902952e+04\n",
      "   2.83710063e+05  1.77362357e+05  2.89349761e+05  3.87127102e+05\n",
      "  -8.35423055e+03  1.04658973e+05  1.11732239e+05  3.59501425e+05\n",
      "  -9.53370186e+04  2.90158580e+05  3.01787254e+05  6.97915963e+04\n",
      "   4.09854973e+05  2.98696074e+05  8.25287593e+04  1.24291437e+05\n",
      "   2.31859512e+03 -2.94822138e+04 -1.76067180e+05  2.29303223e+05\n",
      "   3.19686648e+02 -3.01495860e+05 -1.03250604e+05  1.55859333e+05\n",
      "  -2.55660176e+04  1.00657041e+04  1.20858576e+05 -4.50537083e+05\n",
      "  -2.11290731e+04  2.47637716e+05 -1.30888909e+05  2.98352775e+05\n",
      "  -1.50719961e+04 -1.89946675e+03  5.92002564e+04 -1.19428016e+05\n",
      "  -2.21064061e+05  2.64545977e+05  8.40943752e+03 -7.49461305e+03\n",
      "  -3.74646019e+04  7.71111444e+04  2.79793093e+04 -4.04611092e+05\n",
      "   1.16442011e+05 -1.60585851e+05  5.11177100e+04 -4.32536272e+05\n",
      "   1.60132465e+04 -7.93544926e+04 -4.07286801e+05  4.89154170e+04\n",
      "   8.08473185e+04 -7.12624570e+04  3.86663656e+04  2.89497541e+05\n",
      "   4.94329404e+03 -1.61412188e+05  2.62034861e+05 -5.96591733e+04\n",
      "   1.50787394e+05  2.72656184e+05 -2.74923499e+05  2.09326902e+05\n",
      "   1.37897551e+05  2.41442539e+05  1.63006114e+05 -2.84944748e+05\n",
      "  -7.29904201e+04 -1.85904039e+04 -1.95422956e+04  8.88366943e+04\n",
      "   1.52387555e+04 -3.54715174e+05 -3.58430520e+04  6.31413614e+04\n",
      "  -1.89279003e+05  2.89010576e+05 -1.51148373e+05  6.32982559e+04\n",
      "  -1.31547502e+05  2.14598997e+05  2.59134161e+05  1.62633736e+05\n",
      "  -3.64427680e+04 -3.36084268e+05 -7.81378480e+04 -1.02218681e+05\n",
      "  -8.51318042e+04  1.34705603e+05 -2.23314417e+04 -4.78918404e+04\n",
      "   7.19072927e+04 -3.76055546e+04  3.19894941e+04  1.43779415e+05\n",
      "  -2.53266370e+05 -8.51455522e+04  8.99167366e+03 -3.25520145e+04\n",
      "  -2.87692307e+05  2.08250619e+05 -1.46381249e+05  8.52005493e+03\n",
      "  -1.52185130e+05  8.53520499e+04 -2.01133139e+05  2.74973451e+05\n",
      "  -1.27164637e+05  4.31647034e+04 -3.00959424e+04 -8.21700942e+04\n",
      "  -2.09878538e+04 -2.53613550e+05  3.61812358e+04  4.28617272e+04\n",
      "   6.69636292e+04 -2.79194356e+05  2.45400685e+04 -6.32063859e+04\n",
      "  -8.51306016e+04 -7.70090629e+04  1.14745968e+05 -1.98222689e+05\n",
      "  -1.17160360e+05  2.53669474e+05  7.55819695e+04 -3.95456947e+04\n",
      "   1.59949880e+05  1.15627524e+05  9.43169971e+04 -1.55263488e+05\n",
      "   2.41330040e+05  4.26206108e+04 -2.69905433e+04 -1.41466036e+05\n",
      "   5.29522262e+04  1.94289713e+05 -4.09678513e+05 -6.18061285e+04\n",
      "  -1.21185041e+05 -2.69576885e+05  2.27919942e+05 -6.65316963e+04\n",
      "  -1.99694662e+05 -3.32950475e+04 -1.90594776e+04 -3.15295724e+04\n",
      "   8.61492088e+04 -7.79016517e+04 -8.86368184e+04 -9.47742802e+04\n",
      "   2.28355808e+05  9.71912982e+04 -1.40892906e+05 -8.88030669e+04\n",
      "   2.11746442e+05 -6.24448814e+04 -1.27164546e+05 -9.67289306e+04\n",
      "   1.18926050e+05  2.56664541e+05 -2.62444296e+04  8.32292240e+04\n",
      "   2.09887013e+04 -2.00731446e+04  3.39834666e+04  2.75984123e+04\n",
      "   1.38598700e+05  7.45955146e+04 -1.88866697e+05  2.37586876e+04\n",
      "  -1.59396259e+05 -1.37756426e+05 -1.22201367e+05  8.00714338e+04\n",
      "   1.85220501e+05 -1.58587322e+04 -1.95303264e+05 -1.75220911e+04\n",
      "   2.58467336e+05  1.11701178e+05 -2.55159141e+05  4.71059468e+05\n",
      "  -9.15016562e+04 -2.12872365e+05 -2.85114587e+04 -1.49498205e+05\n",
      "  -3.52627340e+04  8.79450487e+04  9.88240484e+04 -2.21462797e+05\n",
      "  -4.15229465e+04 -3.63815186e+04 -3.02262087e+04  1.37518443e+05\n",
      "  -2.34801554e+05  1.71678894e+05  1.03704978e+05 -2.55123181e+05\n",
      "  -1.79579178e+05  2.38521145e+05 -1.45418567e+05 -2.96381395e+05\n",
      "   9.99403202e+03  1.33457587e+05 -3.48072799e+05 -2.13041113e+04\n",
      "  -2.90354144e+05 -2.27384234e+05 -6.60015723e+04  7.47513325e+04\n",
      "  -8.23259331e+04  3.49555212e+05  1.41240354e+05 -6.98769225e+04\n",
      "   2.38111200e+05  2.44494062e+05  1.40788217e+05  8.30285531e+04\n",
      "   1.23339876e+05  1.05293976e+05 -5.63046340e+02 -1.75577132e+05\n",
      "  -8.48826900e+04  2.08180174e+05 -1.81222617e+05 -9.61948425e+04\n",
      "  -5.78138532e+03  1.02410183e+05  1.02601790e+04  2.31887585e+05\n",
      "   2.59266750e+04 -8.02922041e+04 -3.30644542e+05 -1.63494382e+02\n",
      "   7.89764103e+04  8.49429940e+04  6.61645964e+04  8.14188421e+04\n",
      "  -7.68046040e+04  1.98123240e+05  5.89289820e+04 -1.61269810e+04\n",
      "   3.27223671e+04 -2.78958559e+05 -8.55118251e+04  1.28561961e+05\n",
      "   1.70170271e+05 -9.57741765e+04  2.36154655e+04  5.72133888e+04\n",
      "   1.17166222e+05 -8.61599743e+04  8.32261964e+04  8.24682347e+04\n",
      "  -1.84978559e+05 -1.19625713e+05  5.14634298e+04  1.99060782e+05\n",
      "  -1.26745778e+05  2.49466831e+05  2.73728913e+04 -3.78917627e+05\n",
      "  -4.18965934e+04  7.99746542e+02 -1.85841265e+03  1.55061058e+05\n",
      "  -1.42170992e+05  3.17933578e+04  2.18321518e+05 -1.51087729e+05\n",
      "  -2.02802216e+05  2.00780884e+05  1.69975975e+04 -6.64307508e+04\n",
      "  -8.63018215e+03  3.24165440e+04 -3.89155750e+05  7.53570080e+04\n",
      "   2.65426540e+05 -6.22657136e+04 -6.78010072e+04 -9.90775275e+04\n",
      "  -1.19177474e+05 -2.57208997e+05  2.93971656e+05 -8.72673997e+04\n",
      "  -1.16669235e+05  9.54133283e+04  9.09152294e+04 -1.09626436e+05\n",
      "   1.04851935e+05  1.79224162e+05  6.17623694e+04 -2.16161035e+05\n",
      "   9.89112690e+04  5.11874016e+04  3.73345204e+05  1.24942353e+05\n",
      "   6.14438138e+04  5.32758435e+04 -1.12430680e+05  6.28655695e+04\n",
      "  -2.15175339e+05 -4.56334421e+04  2.90210627e+04 -1.00837115e+05\n",
      "   3.83975922e+04  1.00630779e+05  2.19605764e+04 -3.52719179e+04\n",
      "   5.80502042e+04  2.24509329e+04 -1.59868599e+04 -1.12723615e+05\n",
      "   2.76791882e+05 -1.19829920e+05  7.47275616e+04  1.11950023e+05\n",
      "  -2.36609577e+05 -2.72521351e+04 -1.07333909e+05 -1.78373206e+05\n",
      "  -1.81809676e+05  9.08509840e+04  2.40043440e+04 -3.39015010e+04\n",
      "  -1.90731090e+04 -2.86378596e+04 -3.10101981e+04  1.10118998e+05\n",
      "   3.77296300e+04 -8.94352045e+04 -2.53542801e+05  2.88020247e+04\n",
      "   3.42968257e+04 -2.28216610e+05  1.40793001e+05  1.73707434e+05\n",
      "  -6.31930280e+04 -2.05971987e+05 -5.91571602e+04  2.51220784e+04\n",
      "  -1.95644157e+05  1.70738405e+05 -8.23269632e+04 -1.25977292e+05\n",
      "  -1.38867474e+05  1.23402644e+05  2.05639019e+05 -7.74279901e+04\n",
      "   1.34265522e+05  1.44010071e+05 -7.63899387e+03  1.21072572e+05\n",
      "   5.87442349e+04 -1.50539784e+05  4.20074913e+04 -2.49273746e+04\n",
      "  -1.25512013e+05 -1.55550598e+05  4.11957553e+05  1.77748923e+05\n",
      "  -2.79212691e+05 -1.93148969e+05 -4.33721620e+04  5.92712839e+04\n",
      "  -1.75883237e+05  2.16224443e+05 -9.72832689e+04  1.67887589e+05\n",
      "  -7.25199701e+03 -7.17507853e+04  1.64193049e+05 -7.54532499e+03\n",
      "  -4.22036937e+04  8.26888077e+04  2.18117389e+05 -1.61475117e+05\n",
      "  -3.34637954e+05 -1.24568943e+05 -2.01390032e+05  8.69929410e+04\n",
      "   2.24523845e+05  1.68985985e+05  9.05842772e+04 -5.78446724e+04\n",
      "   2.85722908e+04 -1.60743502e+05 -2.77200634e+05  2.89774931e+05\n",
      "   2.24944822e+05 -3.30113329e+05 -1.27622841e+05  3.08769337e+04\n",
      "   3.77156939e+05  2.91255701e+05  1.58546618e+05 -8.13201811e+04\n",
      "   1.12955512e+05 -8.20887762e+04 -4.72303219e+04  9.37202471e+04\n",
      "   3.47621165e+05  1.82166378e+04  1.84333745e+05 -4.45059788e+04\n",
      "  -1.40545588e+05 -7.96018347e+04 -9.88479462e+03 -1.42354704e+05\n",
      "   1.06481528e+05  3.39732237e+04  4.86853179e+03  6.68170482e+03\n",
      "  -3.23962993e+05  1.56580710e+04  6.87731761e+04  3.10789116e+05\n",
      "   1.53397436e+05  1.26606541e+05 -3.95002708e+05 -3.82627878e+05\n",
      "  -2.39595661e+05  5.44362284e+04 -2.81527165e+04 -8.37732790e+04\n",
      "   6.49532496e+04 -2.88239402e+05 -1.29936485e+05 -1.47425829e+05\n",
      "  -2.57740908e+04  1.84403192e+05 -1.25623305e+05  2.72290256e+05\n",
      "  -9.64986817e+04  2.96687879e+04  1.34712763e+05  1.41586125e+04\n",
      "  -5.25424792e+04 -1.57326054e+05  1.74907479e+05  8.68419739e+04\n",
      "   9.91368592e+04 -9.29704314e+04 -2.74121391e+05  1.72227410e+05\n",
      "  -5.05225751e+04 -7.18634912e+04 -9.34758661e+04 -1.46878622e+05\n",
      "  -1.26223539e+05 -1.91610824e+05  1.25500852e+05 -4.61878621e+04\n",
      "   3.52926407e+04 -4.04738540e+04  1.65128087e+05  9.41060537e+04\n",
      "  -4.22151530e+04  2.12014750e+05  1.09113860e+05 -7.84633906e+04\n",
      "   3.48759992e+05]]\n"
     ]
    }
   ],
   "source": [
    "a=20\n",
    "X=linear_equation(A,b,a)#调用方法，用解方程组的方法求解线性回归模型参数值并返回给X\n",
    "print(X.shape)\n",
    "print(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
